package com.kdd.campus.sh.config;

import com.alibaba.fastjson.JSONObject;
import com.kdd.campus.common.entity.CommonResult;
import com.kdd.campus.common.util.RedisUtil;
import com.kdd.campus.sh.component.JwtAuthenticationTokenFilter;
import com.kdd.campus.sh.component.RestAuthenticationEntryPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

/**
 * @Auther: fcp
 * @Date: 2020/4/22 21:43
 * @Description:
 */
@EnableWebSecurity
// 开启权限注解，默认是关闭
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    private final Logger LOGGER = LoggerFactory.getLogger(SpringSecurityConfig.class);

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        super.configure(auth);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        for (String url : ignoreUrlsConfig().getUrls()) {
            // 添加不需要认证的白名单路径
            registry.antMatchers(url).permitAll();
        }

        registry
                .anyRequest().authenticated()
                // 基于Token不需要session
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                //禁用缓存
                .and().headers().cacheControl();

        http
            .csrf().disable()
            // 添加自定义的JWT过滤器
            .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)
            // 自定义权限拒绝处理类
            .exceptionHandling()
                .authenticationEntryPoint(restAuthenticationEntryPoint())

            // 自定义注销策略
            .and().logout().logoutUrl("/logout").logoutSuccessHandler((request, response, authentication)->{
                // 退出登录后清除Redis中的Token
                String token = request.getHeader(tokenHeader);
                if (token!=null && token.startsWith(tokenHead)){
                    String authToken = token.substring(tokenHead.length()+1);
                    RedisUtil.del(authToken);
                }

                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");
                response.getWriter().println(JSONObject.toJSONString(CommonResult.success(null ,"退出登录成功" )));
                response.getWriter().flush();
            });
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
        return new JwtAuthenticationTokenFilter();
    }

    @Bean
    public IgnoreUrlsConfig ignoreUrlsConfig(){
        return new IgnoreUrlsConfig();
    }

    @Bean
    public RestAuthenticationEntryPoint restAuthenticationEntryPoint(){
        return new RestAuthenticationEntryPoint();
    }


}
